package cemp.service;

import cemp.common.dto.request.StockLoginRequestDto;
import cemp.common.dto.request.StockSysUserRequestDto;
import cemp.entity.StockSysUser;
import cemp.jwt.JwtCommonUser;
import cemp.jwt.JwtTokenUtil;
import cemp.mapper.StockSysUserMapper;
import cemp.redis.constant.RedisKey;
import cemp.redis.util.RedisUtils;
import cemp.shiro.OAuth2Token;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;

@RequiredArgsConstructor
@Slf4j
@Service
public class StockSysUserService {

    @Resource
    private final StockSysUserMapper stockSysUserMapper;
    @Resource
    private final RedisUtils redisUtils;


    /**
     * 生成盐
     * @return
     */
    private String generateSalt(){
        byte[] salt = new byte[16];
        new SecureRandom().nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);

    }

    private StockSysUser getByName(String username){
        return stockSysUserMapper.getByName(username);
    }


    public String login(StockLoginRequestDto login) throws Exception {
        //匹配数据库
        StockSysUser user = getByName(login.getUsername());
        //对password加密并和数据库比较
        boolean passRight = user != null && user.getPassword().equals(new Sha256Hash(login.getPassword(), user.getSalt()).toHex()) ;
        //生成jwt token
        if(passRight){
            JwtCommonUser commonUser = new JwtCommonUser();
            commonUser.setOpenid(user.getOpenid());
            commonUser.setUserId(Long.valueOf(user.getId()));
            String token = JwtTokenUtil.generateToken(commonUser);
            OAuth2Token tk = new OAuth2Token(token);
            //维护redis
            String key = RedisKey.STOCK_AUTH_USER.concat(user.getId().toString());
            redisUtils.set(key,token,JwtTokenUtil.T_MILS_DAY);
            //执行shiro登录,
            SecurityUtils.getSubject().login(tk);

            return token;
        }
        return null;
    }

    /**
     * 注册
     * @param user
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public void register(StockSysUserRequestDto user) throws InvocationTargetException, IllegalAccessException {
        StockSysUser userEntity = new StockSysUser();
        BeanUtils.copyProperties(user,userEntity);
        //password加密
        String salt =generateSalt();
        String parsedPWD = new Sha256Hash(user.getPassword(), salt).toHex();
        userEntity.setSalt(salt);
        userEntity.setPassword(parsedPWD);
        userEntity.setOpenid(UUID.randomUUID().toString());
        stockSysUserMapper.insert(userEntity);
    }


}
